package com.api.syh56.shengyunhui.service.impl;

import com.api.syh56.shengyunhui.common.BaseUserInfo;
import com.api.syh56.shengyunhui.common.Constants;
import com.api.syh56.shengyunhui.common.UserInfoEnu;
import com.api.syh56.shengyunhui.entity.*;
import com.api.syh56.shengyunhui.entity.vo.CouponVO;
import com.api.syh56.shengyunhui.exception.BaseException;
import com.api.syh56.shengyunhui.mapper.CouponDetMapper;
import com.api.syh56.shengyunhui.mapper.CouponMapper;
import com.api.syh56.shengyunhui.service.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.ibatis.jdbc.Null;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;

@Service
public class CouponDetServiceImpl extends ServiceImpl<CouponDetMapper, CouponDet> implements CouponDetService {

    @Autowired
    private CouponDetMapper couponDetMapper;

    @Autowired
    private QuoteService quoteService;

    @Autowired
    private WayBillService wayBillService;

    @Autowired
    private UserService userService;

    @Autowired
    private PayInfoService payInfoService;

    @Override
    public void insert() {
        Long uid = Long.valueOf(BaseUserInfo.get(UserInfoEnu.id.getCode()));
        HashMap<Short, Integer> couponDetNum = getCouponDetNum();
        HashMap<Short, BigDecimal> couponDetSum = getCouponDetSum();
        HashMap<Short, BigDecimal> couponDetMin = getCouponDetMin();
        LocalDateTime now = LocalDateTime.now();
        for(Short key : couponDetNum.keySet()){
            Integer num = couponDetNum.get(key);
            for (int i = 0 ; i < num ;i++){
                CouponDet couponDet = CouponDet.builder()
                        .couponCode(key)
                        .couponType(Constants.couponType.FULL_REDUCTION)
                        .sum(couponDetSum.get(key))
                        .startDate(now)
                        .endDate(now.plusDays(100))
                        .couponStatus(Constants.couponStatus.EFFECTIVE)
                        .minPurchase(couponDetMin.get(key))
                        .uid(uid)
                        .build();
                couponDetMapper.insert(couponDet);
            }
        }
    }

    /**
     * 获取优惠券最低消费额
     * @return
     */
    private HashMap<Short, BigDecimal> getCouponDetMin() {
        HashMap<Short, BigDecimal> couponDetMin = new HashMap<>();
        couponDetMin.put(Constants.couponCode.TEN,BigDecimal.valueOf(10));
        couponDetMin.put(Constants.couponCode.TWENTY,BigDecimal.valueOf(500));
        couponDetMin.put(Constants.couponCode.FIFTY,BigDecimal.valueOf(1000));
        couponDetMin.put(Constants.couponCode.HUNDRED,BigDecimal.valueOf(2000));
        couponDetMin.put(Constants.couponCode.TWO_HUNDRED,BigDecimal.valueOf(5000));
        couponDetMin.put(Constants.couponCode.FIVE_HUNDRED,BigDecimal.valueOf(10000));
        return couponDetMin;
    }

    /**
     * 获取对应优惠券面额
     * @return
     */
    private HashMap<Short, BigDecimal> getCouponDetSum() {
        HashMap<Short, BigDecimal> couponDetSum = new HashMap<>();
        couponDetSum.put(Constants.couponCode.TEN,BigDecimal.valueOf(10));
        couponDetSum.put(Constants.couponCode.TWENTY,BigDecimal.valueOf(20));
        couponDetSum.put(Constants.couponCode.FIFTY,BigDecimal.valueOf(50));
        couponDetSum.put(Constants.couponCode.HUNDRED,BigDecimal.valueOf(100));
        couponDetSum.put(Constants.couponCode.TWO_HUNDRED,BigDecimal.valueOf(200));
        couponDetSum.put(Constants.couponCode.FIVE_HUNDRED,BigDecimal.valueOf(500));
        return couponDetSum;
    }

    /**
     * 获取对应优惠券数量
     * @return
     */
    private HashMap<Short, Integer> getCouponDetNum() {
        HashMap<Short, Integer> couponDetNum = new HashMap<>();
        couponDetNum.put(Constants.couponCode.TEN,40);
        couponDetNum.put(Constants.couponCode.TWENTY,30);
        couponDetNum.put(Constants.couponCode.FIFTY,20);
        couponDetNum.put(Constants.couponCode.HUNDRED,10);
        couponDetNum.put(Constants.couponCode.TWO_HUNDRED,5);
        couponDetNum.put(Constants.couponCode.FIVE_HUNDRED,2);
        return couponDetNum;
    }

    @Override
    public int getCouponDetNum(Long id) {
        QueryWrapper<CouponDet> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CouponDet::getUid,id)
                        .eq(CouponDet::getCouponStatus,Constants.couponStatus.EFFECTIVE);
        int size = couponDetMapper.selectList(wrapper).size();
        return size;
    }

    @Override
    public BigDecimal getPayAmount(Long qid, Long couponId) {

        Quote quote = quoteService.getById(qid);
        Long wid = quote.getWaybillId();
        BigDecimal PayAmount = BigDecimal.ZERO;
        Waybill waybill = wayBillService.getById(wid);
        if (Constants.WayBillLock.LOCK.equals(waybill.getWaybillLock())){
            throw new BaseException("该订单正在支付中");
        }
        short payMethod = waybill.getPayMethod();
        //现付
        if (Constants.PayMethod.PAY_NOW.equals(payMethod)) {
//            Long cuoId = quote.getCuoId();
//            if (cuoId != null) {
//                System.out.println("couponId:"+cuoId);
//                CouponDet couponDet = couponDetMapper.selectById(cuoId);
//                couponDet.setCouponStatus(Constants.couponStatus.EFFECTIVE);
//                couponDetMapper.updateById(couponDet);
//            }
            PayAmount = quote.getOfferAll();
            if (Objects.isNull(couponId)){
                    quote.setActAmount(PayAmount);
                    quote.setCuoId((long)0);
                    quoteService.updateById(quote);
//                    System.out.println("实付金额:"+quoteService.getById(qid).getActAmount());
                return PayAmount;
            }else{
                CouponDet coupon = getById(couponId);
                Short status = coupon.getCouponStatus();
                int result = PayAmount.compareTo(coupon.getMinPurchase());
                System.out.println(result);
                if (result >= 0 && status.equals(Constants.couponStatus.EFFECTIVE)) {
//                        coupon.setCouponStatus(Constants.couponStatus.IN_USE);
//                        couponDetMapper.updateById(coupon);
                    if (Constants.WayBillLock.LOCK.equals(coupon.getCouLock())){
                        throw new BaseException("优惠券已被使用");
                    }
                    PayAmount = PayAmount.subtract(coupon.getSum());
                    quote.setActAmount(PayAmount);
                    quote.setCuoId(couponId);
                    quoteService.updateById(quote);
//                        System.out.println("实付金额:"+quoteService.getById(qid).getActAmount());
                }else {
                    throw new BaseException("请选择对应金额优惠券或有效优惠券");
                }
            }
            //到付 月结
        }else {
//            Long cuoId = waybill.getCuoId();
//            if (cuoId != null) {
//                CouponDet couponDet = couponDetMapper.selectById(cuoId);
//                couponDet.setCouponStatus(Constants.couponStatus.EFFECTIVE);
//                couponDetMapper.updateById(couponDet);
//            }
            PayAmount = waybill.getOfferAll();
            if (Objects.isNull(couponId)){
                waybill.setActAmount(PayAmount);
                waybill.setCuoId((long)0);
                wayBillService.updateById(waybill);
                return PayAmount;
            }else{
                CouponDet coupon = getById(couponId);
                Short status = coupon.getCouponStatus();
                int result = PayAmount.compareTo(coupon.getMinPurchase());
                System.out.println(result);
                if (result >= 0 && status.equals(Constants.couponStatus.EFFECTIVE)) {
//                    coupon.setCouponStatus(Constants.couponStatus.IN_USE);
//                    couponDetMapper.updateById(coupon);
                    if (Constants.WayBillLock.LOCK.equals(coupon.getCouLock())){
                        throw new BaseException("优惠券已被使用");
                    }
                    PayAmount = PayAmount.subtract(coupon.getSum());
                    waybill.setActAmount(PayAmount);
                    waybill.setCuoId(couponId);
                    wayBillService.updateById(waybill);
                }else {
                    throw new BaseException("请选择对应金额优惠券或有效优惠券");
                }
            }
        }
        System.out.println(PayAmount);
        return PayAmount;
    }

    @Override
    public void restore(Long qid) {
        Quote quote = quoteService.getById(qid);
        Long waybillId = quote.getWaybillId();
        Waybill waybill = wayBillService.getById(waybillId);
        waybill.setWaybillLock(Constants.WayBillLock.UNLOCK);
        short payMethod = waybill.getPayMethod();
        //现付 去除 更改运单状态 cid quoteAct
        if (Constants.PayMethod.PAY_NOW.equals(payMethod)) {
            System.out.println("现付");
            if (Constants.WaybillStatus.DEPOSIT_PAID.equals(waybill.getWaybillStatus())){
                waybill.setWaybillLock(Constants.WayBillLock.LOCK);
            }else {
                Long cuoId = quote.getCuoId();
                if (cuoId != null && cuoId != 0) {
                    CouponDet couponDet = couponDetMapper.selectById(cuoId);
                    short couLock = Constants.couponStatus.USED.equals(couponDet.getCouponStatus()) ?
                            Constants.WayBillLock.LOCK : Constants.WayBillLock.UNLOCK;
                    couponDet.setCouLock(couLock);
                    couponDetMapper.updateById(couponDet);
                    quote.setCuoId((long)0);
                    quote.setActAmount(quote.getOfferAll());
                    quoteService.updateById(quote);
                }
            }
            wayBillService.updateById(waybill);
            //到付
        }else {
            System.out.println("到付");

            if (Constants.WaybillStatus.SETTLED.equals(waybill.getWaybillStatus())) {
                waybill.setWaybillLock(Constants.WayBillLock.LOCK);
            }else {
                waybill.setWaybillLock(Constants.WayBillLock.UNLOCK);
            }
            Long cuoId = waybill.getCuoId();
            if (cuoId != null && cuoId != 0) {
                CouponDet couponDet = couponDetMapper.selectById(cuoId);
                short couLock = Constants.couponStatus.USED.equals(couponDet.getCouponStatus()) ?
                        Constants.WayBillLock.LOCK : Constants.WayBillLock.UNLOCK;
                couponDet.setCouLock(couLock);
                couponDetMapper.updateById(couponDet);
                waybill.setCuoId((long)0);
                waybill.setActAmount(waybill.getOfferAll());
            }
            wayBillService.updateById(waybill);
        }
    }

    @Override
    public List<CouponDet> updateByUid(Long id) {
        QueryWrapper<CouponDet> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CouponDet::getUid,id)
                .eq(CouponDet::getCouponStatus,Constants.couponStatus.EFFECTIVE);
        List<CouponDet> couponDets = couponDetMapper.selectList(wrapper);
        return couponDets;
    }

    @Override
    public Page<CouponVO> getCoupon(Long uid, Integer pageNum, Integer pageSize, Short couponStatus) {
        QueryWrapper<CouponDet> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(CouponDet::getUid,uid)
                .eq(CouponDet::getCouponStatus, couponStatus)
                .orderByDesc(CouponDet::getCouponCode);
        List<CouponDet> couponDets = couponDetMapper.selectList(wrapper);
        List<CouponVO> couponVOS = new ArrayList<>();
        for (CouponDet couponDet : couponDets){
            CouponVO couponVO = new CouponVO();
            BeanUtils.copyProperties(couponDet,couponVO);
            BigDecimal minPurchase = couponDet.getMinPurchase();
            int minPur = minPurchase.intValue();
            if (minPur == 10){
                couponVO.setMinPurchase("任意金额");
            }else {
                couponVO.setMinPurchase(minPur+"元");
            }
            couponVOS.add(couponVO);
        }
        Page<CouponVO> couponVOPage = new Page<>(pageNum,pageSize);
        couponVOPage.setTotal(couponVOS.size());
        couponVOPage.setRecords(couponVOS);
        return couponVOPage;
    }
}
